package org.rency.common.memcache.support.annotation.advice;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import javax.annotation.Resource;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.rency.common.memcache.service.MemcachedService;
import org.rency.common.memcache.support.annotation.MCacheDomain;
import org.rency.common.memcache.support.annotation.MCacheInvalid;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Aspect
@Order(1000)
public class MCacheInvalidAdvice<T> extends MCacheAdviceBase {
	
	@Resource(name="memcachedService")
	private MemcachedService memcacheService;

	@Pointcut("@annotation(org.rency.common.memcache.support.annotation.MCacheInvalid)")
    private void cacheInvalid() {}
	
	@SuppressWarnings("unchecked")
	@Around("cacheInvalid()")
	public Object aroundCacheInvalid(ProceedingJoinPoint pjp) throws Throwable {
		long startTime = System.currentTimeMillis();
		T ret = null;
		MCacheDomain domain = null;
		
		try {
            Method currentMethod = getCurrentMethod(pjp);
            Annotation annotation = getMethodAnnotation(currentMethod, MCacheInvalid.class);
            domain = buildCacheKey(pjp, currentMethod, annotation);
            if(domain == null){
            	throw new RuntimeException("cache annotation error !");
            }
        } catch (Throwable t) {
        	logger.warn("cache aop inner error！", t);
        }
		try {
			memcacheService.deleteDataWithNoReply(domain);
			ret = (T) pjp.proceed();
		} catch (Throwable t) {
         	logger.warn("cache aop inner error，can not invalid cache data！", t);
        }finally{
        	long endTime = System.currentTimeMillis();
     		logger.info("invalid cache data use :{}ms, key:{}", (endTime - startTime), domain.getCacheKey()); 
        }
		return ret;
	}
	
}
